package io.jpress.core.editor;

import io.jpress.JPressConfig;
import io.jpress.JPressConsts;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class EditorManager {

    private static final EditorManager me = new EditorManager();

    public static EditorManager me() {
        return me;
    }

    private Map<String, EditorInfo> editorInfoMap = new ConcurrentHashMap<>();
    private ThreadLocal<EditorInfo> currentEditorTL = new ThreadLocal<>();
    private EditorInfo defaultEditor;

    public void init() {
        EditorInfo ace = new EditorInfo();
        ace.setId("ace");
        ace.setHtmlFile("/WEB-INF/editors/ace/content.html");
        ace.setJsFile("/WEB-INF/editors/ace/js.html");
        ace.setEditMode(JPressConsts.EDIT_MODE_HTML_SOURCE);
        addEditor(ace);

        EditorInfo ckeditor4 = new EditorInfo();
        ckeditor4.setId("ckeditor4");
        ckeditor4.setHtmlFile("/WEB-INF/editors/ckeditor4/content.html");
        ckeditor4.setJsFile("/WEB-INF/editors/ckeditor4/js.html");
        addEditor(ckeditor4);

        EditorInfo ckeditor5 = new EditorInfo();
        ckeditor5.setId("ckeditor5");
        ckeditor5.setHtmlFile("/WEB-INF/editors/ckeditor5/content.html");
        ckeditor5.setJsFile("/WEB-INF/editors/ckeditor5/js.html");
        addEditor(ckeditor5);


        EditorInfo wangEditor = new EditorInfo();
        wangEditor.setId("wangEditor");
        wangEditor.setHtmlFile("/WEB-INF/editors/wangEditor/content.html");
        wangEditor.setJsFile("/WEB-INF/editors/wangEditor/js.html");
        addEditor(wangEditor);


        EditorInfo vditor = new EditorInfo();
        vditor.setId("vditor");
        vditor.setHtmlFile("/WEB-INF/editors/vditor/content.html");
        vditor.setJsFile("/WEB-INF/editors/vditor/js.html");
        vditor.setEditMode(JPressConsts.EDIT_MODE_MARKDOWN);
        addEditor(vditor);



    }


    public void useHtmlEditor(){
        useEditorByEditMode(JPressConsts.EDIT_MODE_HTML);
    }

    public void useEditorByEditMode(String editMode){
        List<EditorInfo> macthedEditors = new LinkedList<>();

        editorInfoMap.forEach((s, editorInfo) -> {
            if (editMode.equals(editorInfo.getEditMode())){
                macthedEditors.add(editorInfo);
            }
        });

        if (macthedEditors.isEmpty()){
            return;
        }

        if (macthedEditors.size() == 1){
            setCurrentEditor(macthedEditors.get(0));
        }

        boolean setted = false;
        for (EditorInfo machtedEditor : macthedEditors) {
            if (machtedEditor.equals(getDefaultEditor())){
                setted = true;
                setCurrentEditor(machtedEditor);
            }
        }

        if (!setted){
            setCurrentEditor(macthedEditors.get(0));
        }
    }


    public void setCurrentEditor(String name) {
        if (!editorInfoMap.containsKey(name)){
            throw new IllegalStateException("Editor not exists!");
        }
        currentEditorTL.set(getEditor(name));
    }


    public void setCurrentEditor(EditorInfo editorInfo){
        currentEditorTL.set(editorInfo);
    }


    public EditorInfo getCurrentEditor() {
        EditorInfo currentEditor = currentEditorTL.get();
        if (currentEditor == null) {
            currentEditor = getDefaultEditor();
        }

        return currentEditor;
    }


    public EditorInfo getDefaultEditor() {
        if (defaultEditor == null) {
            defaultEditor = getEditor(JPressConfig.me.getDefaultEditor());
        }
        return defaultEditor;
    }



    public void addEditor(EditorInfo editorAddonInfo) {
        if (editorInfoMap.containsKey(editorAddonInfo.getId())) {
            throw new IllegalStateException("Editor exists!");
        }
        editorInfoMap.put(editorAddonInfo.getId(), editorAddonInfo);
    }


    public void removeEditorAddon(String id) {
        editorInfoMap.remove(id);
    }


    public EditorInfo getEditor(String name) {
        return editorInfoMap.get(name);
    }

    public Map<String, EditorInfo> getEditorInfoMap() {
        return editorInfoMap;
    }

    public void setEditorInfoMap(Map<String, EditorInfo> editorInfoMap) {
        this.editorInfoMap = editorInfoMap;
    }
}
